// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

// ************************************************************************* //
//  File: avtPersistentParticlesFilter.h
// ************************************************************************* //

#ifndef AVT_PersistentParticles_FILTER_H
#define AVT_PersistentParticles_FILTER_H

#include <avtExecuteThenTimeLoopFilter.h>
#include <avtPluginFilter.h>

#include <PersistentParticlesAttributes.h>
#include <vtkType.h>
#include <map>
#include <string>
#include <vector>

class vtkPoints;
class vtkDataSet;
class vtkUnstructuredGrid;
class vtkDataSetAttributes;

// ****************************************************************************
//  Class: avtPersistentParticlesFilter
//
//  Purpose:
//      A plugin operator for PersistentParticles. This operator traces 
//      a set of particles based on a given ID variable through time. The
//      operator iterates through the time series and connects the locations
//      of the given particles to compute theit path. The operator creates
//      a new vtkUnstructuredGrid dataset with the pahts as output.
//
//  Programmer: childs -- generated by xml2avt
//  Creation:   Fri Jan 25 11:02:55 PDT 2008
//
// ****************************************************************************

class avtPersistentParticlesFilter 
   : virtual public avtPluginFilter,
     virtual public avtExecuteThenTimeLoopFilter
{
  public:
                         avtPersistentParticlesFilter();
    virtual             ~avtPersistentParticlesFilter();

    static avtFilter    *Create();

    virtual const char  *GetType(void)  { return "avtPersistentParticlesFilter"; };
    virtual const char  *GetDescription(void)
                             { return "PersistentParticles"; };

    virtual void         SetAtts(const AttributeGroup*);
    virtual bool         Equivalent(const AttributeGroup*);
    virtual void         ExamineContract(avtContract_p);

  protected:
    PersistentParticlesAttributes   atts;
    std::vector<avtDataTree_p>      trees;
    std::map<double, vtkIdType>        particlePaths;
    vtkUnstructuredGrid*            particlePathData;


    virtual void                    Execute(void);
    virtual void                    InspectPrincipalData(void);
    virtual void                    Iterate(int, avtDataTree_p);
    virtual void                    Finalize(void);
    virtual avtContract_p           ModifyContract(avtContract_p);  
    virtual void                    UpdateDataObjectInfo(void);

  private:
    void IterateMergeData(int, avtDataTree_p);
    void IterateTraceData(int, avtDataTree_p);

    void ComputeGlobalSizeAndOffset( vtkDataArray *indexVariable,
                                     int *numPerProc,
                                     int &globalSize, int &myOffset) const;

    void GlobalizeData( vtkDataArray *indexVariable, const int component,
                        const int globalSize, const int myOffset,
                        double *&alIds, int *&allIndexes) const;
  
    void GlobalizeData( vtkPoints *currPoints,
                        vtkDataArray *currXData,
                        vtkDataArray *currYData,
                        vtkDataArray *currZData,
                        int globalSize, int myOffset,
                        double *&allPoints) const;

    void GlobalizeData( vtkDataSetAttributes *attributes,
                        const int globalSize, const int myOffset,
                        int &nComponents, double *&allData) const;

    void GetDecomp( int *numPerProc,
                    int &firstIndex,
                    int &lastIndex,
                    int &total ) const;

    std::string mainVariable;   
    int activeTimeStep;
    int startTimeSlice;
    int stopTimeSlice;
    bool haveData;
};
#endif
